package org.boot.service;

import jakarta.annotation.Resource;
import org.boot.dao.AccountDao;
import org.boot.entity.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.PrintStream;
import java.math.BigDecimal;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class AccountServiceImpl implements AccountService {

    private final RiskAssessor riskAssessor;

    private final PrintStream out;

    @Resource
    private AccountDao accountDao;

    @Autowired
    public AccountServiceImpl(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
        this.out = System.out;
    }

    public AccountServiceImpl(RiskAssessor riskAssessor, PrintStream out) {
        this.riskAssessor = riskAssessor;
        this.out = out;
    }

    @Override
    public String getX(String name) {
        out.println("System.out-----------");
        return "MyAccountService - " + riskAssessor.getWord() + " : " + name;
    }

    private Lock lock = new ReentrantLock();

    @Override
    public void updatePayment(Long accountId, BigDecimal amount) {
        try {
            lock.lock();
            Account account = accountDao.getReferenceById(accountId);
            BigDecimal newBalance = account.getBalance().add(amount);
            account.setBalance(newBalance);
            accountDao.save(account);
        } finally {
            lock.unlock();
        }
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void updatePaymentWithDbLock(Long accountId, BigDecimal amount) {
        Account account = accountDao.selectForUpdate(accountId);
        BigDecimal newBalance = account.getBalance().add(amount);
        account.setBalance(newBalance);
        accountDao.save(account);
    }
}
